﻿using EmailClient.Mail;
using EmailClient.Model;
using EmailClient.View;
using EmailClient.ViewModel;
using MahApps.Metro.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace EmailClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : MetroWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            FillTree();

            //DispatcherTimer setup
            var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            dispatcherTimer.Interval = new TimeSpan(0, 0, 10);
            dispatcherTimer.Start();
        }

        private async void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(tbStringSearch.Text)) await UpdateGrid();
        }

        private async void FillTree()
        {
            await UpdateTree();
        }

        public async Task<string> UpdateTree()
        {
            var listAccounts = await AccountViewModel.GetList();
            tvBox.Items.Clear();
            if (listAccounts.Count > 0)
            {
                foreach (var item in listAccounts)
                {
                    var listFolders = await MailFolderViewModel.GetFolders(item.Id);
                    if (item.MailType == "POP3")
                    {
                        var root = new MenuItemUnic() { Title = item.Email, account = item };
                        foreach (var fold in listFolders)
                        {
                            var childItem = new MenuItemUnic() { Title = fold.Name, folderId = fold.Id, account = item };
                            root.Items.Add(childItem);
                        }
                        tvBox.Items.Add(root);
                    }

                    //Create connect to an IMAP box
                    if (item.MailType == "IMAP")
                    {
                        var root = new MenuItemUnic() { Title = item.Email, account = item };
                        foreach (var fold in listFolders)
                        {
                            if (fold.ParentId > 0) continue;
                            var childItem = new MenuItemUnic() { Title = fold.Name, folderId = fold.Id, account = item };
                            var res = from child in listFolders
                                      where child.ParentId == fold.Id
                                      select child;
                            foreach (var i in res)
                            {
                                childItem.Items.Add(new MenuItemUnic() { Title = i.Name, folderId = i.Id, account = item, Parent = fold.Name });
                            }
                            root.Items.Add(childItem);
                        }
                        tvBox.Items.Add(root);
                    }
                }
            }
            return "success";
        }

        public async Task<string> UpdateGrid()
        {
            var result = "success";

            if (tvBox.SelectedItem != null && Common.isConnectionAvailable())
            {
                var sortInfo = new List<SortDescription>();
                foreach (var item in dgLetters.Items.SortDescriptions)
                {
                    sortInfo.Add(item);
                }

                List<ColumnInfo> columnInfos = new List<ColumnInfo>();
                foreach (var column in dgLetters.Columns)
                {
                    columnInfos.Add(new ColumnInfo() { SortMemberPath = column.SortMemberPath, SortDirection = column.SortDirection });
                }


                var curFolder = tvBox.SelectedItem as MenuItemUnic;
                try
                {
                    if (curFolder.account.MailType == "POP3") dgLetters.DataContext = await LetterViewModel.GetList(curFolder.account, curFolder.folderId);
                    else
                    {
                        var folder = await MailFolderViewModel.GetFolder(curFolder.account.Id, curFolder.folderId);
                        var path = await IMAP.GetPathFolder(folder);
                        var imapClient = new IMAP();
                        imapClient.client = IMAP.CreateConnect(curFolder.account);
                        imapClient.folderId = curFolder.folderId;
                        imapClient.account = curFolder.account;
                        result = await imapClient.LoadFolderMessages(path);
                        dgLetters.DataContext = imapClient.letters;
                    }
                    if (dgLetters.Items.SortDescriptions.Count == 0) sortInfo.Add(new SortDescription() { Direction = ListSortDirection.Descending, PropertyName = "DepartureDate" });
                }
                catch (Exception e)
                { result = e.Message; }
                if (result != "success") await LogViewModel.InsertUpdate(new Log() { Event = result, DateEvent = DateTime.Now, AccountId = curFolder.account.Id });
                else
                {
                    foreach (var item in sortInfo)
                    {
                        dgLetters.Items.SortDescriptions.Add(item);
                    }

                    foreach (var columnInfo in columnInfos)
                    {
                        var column = dgLetters.Columns.FirstOrDefault(col => col.SortMemberPath == columnInfo.SortMemberPath);
                        if (column != null)
                        {
                            column.SortDirection = columnInfo.SortDirection;
                            //column.DisplayIndex = columnInfo.DisplayIndex;
                            //column.Visibility = columnInfo.Visibility;
                        }
                    }
                }
            }
            return result;
        }

        public async void GetLettersPOP3()
        {
            if (tvBox.SelectedItem != null)
            {
                var account = ((MenuItemUnic)(tvBox.SelectedItem)).account;
                if (account.MailType == "POP3") await POP3.GetLetters(account);
            }
        }

        private void miCreate_Click(object sender, RoutedEventArgs e)
        {
            if (tvBox.SelectedItem != null)
            {
                var curAccount = ((MenuItemUnic)(tvBox.SelectedItem)).account;
                var newEmail = new LetterView(curAccount);
                newEmail.Show();
            }
        }

        private async void miDelete_Click(object sender, RoutedEventArgs e)
        {
            if (tvBox.SelectedItem != null)
            {
                var curFolder = tvBox.SelectedItem as MenuItemUnic;
                var uids = new List<long>();
                foreach (var row in dgLetters.SelectedCells)
                {
                    if (row.Item != null)
                    {
                        var letter = row.Item as Letter;
                        if (letter.Account.MailType == "POP3") await LetterViewModel.Delete(letter);
                        else uids.Add(letter.UID);
                    }
                }
                if (uids.Count > 0) await IMAP.DeleteLetters(curFolder.account, curFolder.folderId, uids.ToArray());
                await UpdateGrid();
            }
        }

        private async void miSearching_Click(object sender, RoutedEventArgs e)
        {
            if (tvBox.SelectedItem != null)
            {
                var curFolder = tvBox.SelectedItem as MenuItemUnic;
                if (curFolder.account.MailType == "POP3") dgLetters.DataContext = await POP3.Searching(curFolder.account, curFolder.folderId, tbStringSearch.Text.ToUpper());
                else dgLetters.DataContext = await IMAP.Searching(curFolder.account, curFolder.folderId, tbStringSearch.Text.ToUpper());
            }
        }

        private void miSettingsAccounts_Click(object sender, RoutedEventArgs e)
        {
            new SettingsView().Show();
        }

        private void miExit_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void miAbout_Click(object sender, RoutedEventArgs e)
        {
            new AboutView().Show();
        }


        private async void tvBox_GotFocus(object sender, RoutedEventArgs e)
        {
            dgLetters.DataContext = null;           
            await UpdateGrid();
        }

        private void tvBox_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (tvBox.SelectedItem != null)
            {
                var SelectedItem = tvBox.SelectedItem as MenuItemUnic;
                if (SelectedItem.folderId != 0) tvBox.ContextMenu = tvBox.Resources["FolderContext"] as System.Windows.Controls.ContextMenu;
                else tvBox.ContextMenu = null;
            }
        }

        private async void contMenuItemClear_Click(object sender, RoutedEventArgs e)
        {
            if (tvBox.SelectedItem != null)
            {
                var selItem = tvBox.SelectedItem as MenuItemUnic;
                if (selItem.account.MailType == "POP3") await POP3.ClearFolder(selItem.account.Id, selItem.folderId);
                else
                {
                    var curFolder = await MailFolderViewModel.GetFolder(selItem.account.Id, selItem.folderId);
                    var path = await IMAP.GetPathFolder(curFolder);
                    await IMAP.ClearFolder(selItem.account, selItem.folderId, dgLetters.Items);
                }
            }
        }

        private async void drLetters_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (dgLetters.CurrentItem != null)
            {
                var currItem = (Letter)dgLetters.CurrentItem;
                if (currItem.Account.MailType == "POP3")
                {
                    currItem.Attachments = await AttachmentViewModel.GetList(currItem.Id);
                    new LetterView(currItem).Show();
                }
                else
                {
                    if (tvBox.SelectedItem != null)
                    {
                        var curFolder = (EmailClient.Model.MenuItemUnic)(tvBox.SelectedItem);
                        string path = (String.IsNullOrEmpty(curFolder.Parent)) ? curFolder.Title : curFolder.Parent + "/" + curFolder.Title;


                        var imapClient = new IMAP();
                        imapClient.client = IMAP.CreateConnect(currItem.Account);
                        imapClient.account = currItem.Account;
                        imapClient.LoadMessage(currItem.UID, path);
                        if (imapClient.currLetter != null)
                        {
                            imapClient.currLetter.FolderId = curFolder.folderId;
                            new LetterView(imapClient.currLetter).Show();
                        }
                    }
                }
            }
        }

        private void dgLetters_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            var letter = e.Row.Item as Letter;
            if (!letter.Read) e.Row.FontWeight = FontWeights.DemiBold;
            else e.Row.FontWeight = FontWeights.Normal;
        }

    }
}
